home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Contributed / SpriteWorld / SpriteWorld Files / Sources / SpriteWorldUtils.c < prev    next >
Encoding:
Text File  |  2000-10-06  |  45.1 KB  |  1,905 lines  |  [TEXT/CWIE]

  1. ///--------------------------------------------------------------------------------------
  2. //    SpriteWorldUtils.c
  3. //
  4. //    Portions are copyright: © 1991-94 Tony Myles, All rights reserved worldwide.
  5. //
  6. //    Description:    some utilities for creating worlds of sprites
  7. ///--------------------------------------------------------------------------------------
  8.  
  9. #ifndef __QUICKDRAW__
  10. #include <QuickDraw.h>
  11. #endif
  12.  
  13. #ifndef __QDOFFSCREEN__
  14. #include <QDOffscreen.h>
  15. #endif
  16.  
  17. #ifndef __WINDOWS__
  18. #include <Windows.h>
  19. #endif
  20.  
  21. #ifndef __MEMORY__
  22. #include <Memory.h>
  23. #endif
  24.  
  25. #ifndef __GESTALT__
  26. #include <Gestalt.h>
  27. #endif
  28.  
  29. #ifndef __TOOLUTILS__
  30. #include <ToolUtils.h>
  31. #endif
  32.  
  33. #ifndef __TEXTUTILS__
  34. #include <TextUtils.h>
  35. #endif
  36.  
  37. #ifndef __RESOURCES__
  38. #include <Resources.h>
  39. #endif
  40.  
  41. #ifndef __ERRORS__
  42. #include <Errors.h>
  43. #endif
  44.  
  45. #ifndef __SWCOMMON__
  46. #include <SWCommonHeaders.h>
  47. #endif
  48.  
  49. #ifndef __SPRITEWORLD__
  50. #include <SpriteWorld.h>
  51. #endif
  52.  
  53. #ifndef __SPRITELAYER__
  54. #include <SpriteLayer.h>
  55. #endif
  56.  
  57. #ifndef __SPRITE__
  58. #include <Sprite.h>
  59. #endif
  60.  
  61. #ifndef __SPRITEFRAME__
  62. #include <SpriteFrame.h>
  63. #endif
  64.  
  65. #ifndef __SPRITEWORLDUTILS__
  66. #include <SpriteWorldUtils.h>
  67. #endif
  68.  
  69. #ifndef __BLITPIXIEINTERFACE__
  70. #include <BlitPixieInterface.h>
  71. #endif
  72.  
  73. ///-------------------------------------------------------------------------------------
  74.  
  75. #define kSolid            0x00000000UL    // mask solid value (all zeros : "black" *)
  76. #define kClear            0xFFFFFFFFUL    // mask clear value (all ones : "white" *)
  77.  
  78.                 // * In Indexed Color (< 16-bit), the mask IMAGE is inversed (not the actual bits).
  79.                 //   (since the first index is white and the last index is black in a Mac color table)
  80.  
  81.  
  82. #define kAlphaMask16    0x7FFF            // masking value to remove the alpha channel (keep RGB)
  83. #define kAlphaMask32    0x00FFFFFFL
  84.  
  85. ///-------------------------------------------------------------------------------------
  86.  
  87. RGBColor        gSWTransparentColor =    // transparent pixel color
  88.                 {0xFFFF,0xFFFF,0xFFFF};    // default color: white
  89.  
  90. static void     ComputePixelValues( short pixelSize );
  91.  
  92. static UInt16    SWMaskedRGBValue;        // masked pixel R/G/B value (used by the ColorSearch procs)
  93. static UInt16    SWTransparentRGBValue;    // transparent pixel R/G/B value (used by the ColorSearch procs)
  94.  
  95. static OSErr    gSWStickyError;
  96.  
  97.  
  98. ///--------------------------------------------------------------------------------------
  99. // SWCreateRegionFromCIconMask
  100. ///--------------------------------------------------------------------------------------
  101.  
  102. SW_FUNC OSErr SWCreateRegionFromCIconMask(
  103.     RgnHandle *maskRgn,
  104.     CIconHandle cIconH)
  105. {
  106.     OSErr err = noErr;
  107.     RgnHandle tempMaskRgn;
  108.     char saveState;
  109.     BitMap iconMask;
  110.  
  111.     *maskRgn = NULL;
  112.  
  113.     saveState = HGetState((Handle)cIconH);
  114.     HLock((Handle)cIconH);
  115.  
  116.     iconMask.rowBytes = (**cIconH).iconMask.rowBytes;
  117.     iconMask.bounds = (**cIconH).iconMask.bounds;
  118.     iconMask.baseAddr = (Ptr)(**cIconH).iconMaskData;
  119.  
  120.     tempMaskRgn = NewRgn();
  121.  
  122.     if (tempMaskRgn != NULL)
  123.     {
  124.         err = BitMapToRegion(tempMaskRgn, &iconMask);
  125.  
  126.         if (err == noErr)
  127.         {
  128.             *maskRgn = tempMaskRgn;
  129.         }
  130.         else
  131.         {
  132.             DisposeRgn(tempMaskRgn);
  133.         }
  134.     }
  135.     else
  136.     {
  137.         err = MemError();
  138.     }
  139.  
  140.     HSetState((Handle)cIconH, saveState);
  141.  
  142.     SWSetStickyIfError( err );
  143.     return err;
  144. }
  145.  
  146. /*
  147. ///--------------------------------------------------------------------------------------
  148. // SWCreateRegionFromPict
  149. ///--------------------------------------------------------------------------------------
  150.  
  151. SW_FUNC OSErr SWCreateRegionFromPict(
  152.     RgnHandle *pictRgnH,
  153.     PicHandle srcPictH)
  154. {
  155.     RgnHandle             tempRgnH;
  156.     GWorldPtr             saveGWorld, 
  157.                         offScrnGWld;
  158.     GDHandle            saveGDH;
  159.     Rect                frameRect;
  160.     ColorSearchUPP        blackenColSearchUPP;
  161.     OSErr                 err;
  162.     
  163.     GetGWorld(&saveGWorld, &saveGDH );
  164.     
  165.     *pictRgnH = NULL;
  166.     frameRect = (**srcPictH).picFrame;
  167.     OffsetRect(&frameRect, -frameRect.left, -frameRect.top);
  168.         
  169.     err = NewGWorld( &offScrnGWld, 1, &frameRect, nil, nil, 0 );
  170.     
  171.     if (err == noErr)
  172.     {    
  173.         blackenColSearchUPP = NewColorSearchProc( blackenColorSearch );
  174.         (void)LockPixels( GetGWorldPixMap(offScrnGWld) );
  175.         SetGWorld(offScrnGWld, nil);
  176.         AddSearch( blackenColSearchUPP );
  177.         EraseRect(&frameRect);
  178.         DrawPicture(srcPictH, &frameRect);
  179.         DelSearch( blackenColSearchUPP );
  180.         DisposeRoutineDescriptor( blackenColSearchUPP );
  181.         tempRgnH = NewRgn();
  182.  
  183.         if (tempRgnH != NULL && err == noErr)
  184.         {
  185.             err = BitMapToRegion(tempRgnH, (BitMap*)*GetGWorldPixMap( offScrnGWld ) );
  186.             
  187.             if (err == noErr)
  188.             {
  189.                 *pictRgnH = tempRgnH;
  190.             }
  191.             else
  192.             {
  193.                 DisposeRgn(tempRgnH);
  194.             }
  195.         }
  196.         else
  197.         {
  198.             if ( err == noErr )
  199.                 err = MemError();
  200.         }
  201.  
  202.         SetGWorld(saveGWorld, nil);
  203.         DisposeGWorld(offScrnGWld);
  204.     }
  205.  
  206.     SWSetStickyIfError( err );
  207.     return err;
  208. }
  209. */
  210.  
  211. ///--------------------------------------------------------------------------------------
  212. // SWCreateRegionFromGWorldAndRect - expects an already blackened maskGWorld.
  213. ///--------------------------------------------------------------------------------------
  214.  
  215. SW_FUNC OSErr SWCreateRegionFromGWorldAndRect(
  216.     RgnHandle *maskRgn,
  217.     GWorldPtr maskGWorld,
  218.     Rect* frameRect)
  219. {
  220.     OSErr             err = noErr;
  221.     GDHandle        saveGDH;
  222.     GWorldPtr         saveGWorld, 
  223.                     tempMaskGWorld;
  224.     Rect            tempMaskRect;
  225.     
  226.     
  227.     *maskRgn = NULL;
  228.     
  229.     GetGWorld(&saveGWorld, &saveGDH);
  230.  
  231.     tempMaskRect = *frameRect;
  232.     OffsetRect(&tempMaskRect, -tempMaskRect.left, -tempMaskRect.top);
  233.     
  234.     err = SWCreateRegionFromGWorldAndRectStart( &tempMaskGWorld, tempMaskRect.right, 
  235.             tempMaskRect.bottom );
  236.     
  237.     if (err == noErr)
  238.     {
  239.         err = SWCreateRegionFromGWorldAndRectPartial( maskRgn, maskGWorld,
  240.                 tempMaskGWorld, frameRect );
  241.         
  242.         SWCreateRegionFromGWorldAndRectFinish( tempMaskGWorld );
  243.     }
  244.  
  245.     SWSetStickyIfError( err );
  246.     return err;
  247. }
  248.  
  249.  
  250. ///--------------------------------------------------------------------------------------
  251. // SWCreateRegionFromGWorldAndRectStart
  252. ///--------------------------------------------------------------------------------------
  253.  
  254. SW_FUNC OSErr SWCreateRegionFromGWorldAndRectStart(
  255.     GWorldPtr *tempMaskGWorld,
  256.     short maxWidth,
  257.     short maxHeight)
  258. {
  259.     OSErr         err = noErr;
  260.     Rect         tempMaskRect;
  261.     
  262.     
  263.     SetRect( &tempMaskRect, 0, 0, maxWidth, maxHeight );
  264.     err = NewGWorld( tempMaskGWorld, 1, &tempMaskRect, nil, nil, 0 );
  265.     if (err == noErr)
  266.     {
  267.         (void)LockPixels( GetGWorldPixMap( *tempMaskGWorld ) );
  268.     }
  269.     
  270.     SWSetStickyIfError( err );
  271.     return err;
  272. }
  273.  
  274.  
  275. ///--------------------------------------------------------------------------------------
  276. // SWCreateRegionFromGWorldAndRectFinish
  277. ///--------------------------------------------------------------------------------------
  278.  
  279. SW_FUNC void SWCreateRegionFromGWorldAndRectFinish(
  280.     GWorldPtr tempMaskGWorld)
  281. {    
  282.     if ( tempMaskGWorld != NULL )
  283.     {
  284.         DisposeGWorld(tempMaskGWorld);
  285.     }
  286. }
  287.  
  288.  
  289. ///--------------------------------------------------------------------------------------
  290. // SWCreateRegionFromGWorldAndRectPartial
  291. ///--------------------------------------------------------------------------------------
  292.  
  293. SW_FUNC OSErr SWCreateRegionFromGWorldAndRectPartial(
  294.     RgnHandle *maskRgn,
  295.     GWorldPtr maskGWorld,
  296.     GWorldPtr tempMaskGWorld,
  297.     Rect* frameRect)
  298. {
  299.     OSErr             err = noErr;
  300.     GDHandle        saveGDH;
  301.     GWorldPtr         saveGWorld;
  302.     Rect            tempMaskRect;
  303.     RgnHandle         tempRgnH;
  304.     
  305.     
  306.     *maskRgn = NULL;
  307.     
  308.     GetGWorld(&saveGWorld, &saveGDH);
  309.  
  310.     tempMaskRect = *frameRect;
  311.     OffsetRect(&tempMaskRect, -tempMaskRect.left, -tempMaskRect.top);
  312.     
  313.     (void)LockPixels( GetGWorldPixMap(maskGWorld) );
  314.     SetGWorld(tempMaskGWorld, nil);
  315.         
  316.     CopyBits(
  317.         (BitMap*)*GetGWorldPixMap( maskGWorld ), 
  318.         (BitMap*)*GetGWorldPixMap( tempMaskGWorld ), 
  319.         frameRect, 
  320.         &tempMaskRect,
  321.         srcCopy, 
  322.         nil );
  323.  
  324.     tempRgnH = NewRgn();
  325.     if (tempRgnH != NULL)
  326.     {
  327.         err = BitMapToRegion(tempRgnH, (BitMap*)*GetGWorldPixMap( tempMaskGWorld ) );
  328.  
  329.         UnlockPixels( GetGWorldPixMap(maskGWorld) );
  330.         
  331.         if (err == noErr)
  332.         {
  333.             *maskRgn = tempRgnH;
  334.         }
  335.         else
  336.         {
  337.             DisposeRgn(tempRgnH);
  338.         }
  339.     }
  340.     else
  341.     {
  342.         err = MemError();
  343.     }
  344.     SetGWorld(saveGWorld, nil);
  345.     
  346.     SWSetStickyIfError( err );
  347.     return err;
  348. }
  349.  
  350. #pragma mark -
  351.  
  352. ///--------------------------------------------------------------------------------------
  353. // SWCreateGWorldFromPictResource
  354. ///--------------------------------------------------------------------------------------
  355.  
  356. SW_FUNC OSErr SWCreateGWorldFromPictResource(
  357.     SpriteWorldPtr destSpriteWorld,
  358.     GWorldPtr *pictGWorldP,
  359.     short pictResID)
  360. {
  361.     OSErr             err = noErr;
  362.     PicHandle         newPictH;
  363.     
  364.     
  365.     newPictH = GetPicture(pictResID);
  366.  
  367.     if (newPictH != NULL)
  368.     {
  369.         err = SWCreateGWorldFromPict(destSpriteWorld, pictGWorldP, newPictH);
  370.  
  371.         ReleaseResource((Handle)newPictH);
  372.     }
  373.     else
  374.     {
  375.         err = ResError();
  376.         if (err == noErr)
  377.         {
  378.             err = resNotFound;
  379.         }
  380.     }
  381.  
  382.     SWSetStickyIfError( err );
  383.     return err;
  384. }
  385.  
  386.  
  387. ///--------------------------------------------------------------------------------------
  388. // SWCreateGWorldFromPict
  389. //    creates a offScreen GWorld and draws the specified pict into it
  390. ///--------------------------------------------------------------------------------------
  391.  
  392. SW_FUNC OSErr SWCreateGWorldFromPict(
  393.     SpriteWorldPtr destSpriteWorld,
  394.     GWorldPtr *pictGWorld,
  395.     PicHandle pictH)
  396. {
  397.     OSErr            err;
  398.     GWorldPtr         saveGWorld;
  399.     GDHandle         saveGDevice;
  400.     GWorldPtr         tempGWorld;
  401.     Rect             pictRect;
  402.     short            depth;
  403.     GDHandle        theGDH;
  404.  
  405.  
  406.     *pictGWorld = NULL;
  407.         
  408.     GetGWorld(&saveGWorld, &saveGDevice);
  409.     
  410.     depth = destSpriteWorld->pixelDepth;
  411.     theGDH = destSpriteWorld->mainSWGDH;
  412.  
  413.     pictRect = (**pictH).picFrame;
  414.     OffsetRect(&pictRect, -pictRect.left, -pictRect.top);
  415.  
  416.     if ( (**((**theGDH).gdPMap)).pixelSize == depth )
  417.         err = NewGWorld( &tempGWorld, depth, &pictRect, nil, theGDH, noNewDevice );
  418.     else
  419.         err = NewGWorld( &tempGWorld, depth, &pictRect, nil, nil, 0 );
  420.     
  421.     if (err == noErr)
  422.     {    
  423.         *pictGWorld = tempGWorld;
  424.         
  425.         SetGWorld(tempGWorld, nil);
  426.         
  427.         (void)LockPixels( GetGWorldPixMap(tempGWorld) );
  428.         EraseRect(&pictRect);
  429.         DrawPicture(pictH, &pictRect);
  430.         UnlockPixels( GetGWorldPixMap(tempGWorld) );
  431.     }
  432.  
  433.     SetGWorld(saveGWorld, saveGDevice);
  434.     
  435.     SWSetStickyIfError( err );
  436.     return err;
  437. }
  438.  
  439.  
  440. ///--------------------------------------------------------------------------------------
  441. // SWCreateGWorldFromCIconMask
  442. ///--------------------------------------------------------------------------------------
  443.  
  444. SW_FUNC OSErr SWCreateGWorldFromCIconMask(
  445.     SpriteWorldPtr destSpriteWorld,
  446.     GWorldPtr *maskGWorldP,
  447.     CIconHandle cIconH)
  448. {
  449.     OSErr             err;
  450.     GWorldPtr         saveGWorld;
  451.     GDHandle         saveGDevice;
  452.     char             saveState;
  453.     BitMap             maskBitMap;
  454.     GWorldPtr         tempGWorldP;
  455.     short            depth;
  456.     GDHandle        theGDH;
  457.  
  458.  
  459.     GetGWorld(&saveGWorld, &saveGDevice);
  460.  
  461.     depth = destSpriteWorld->pixelDepth;
  462.     theGDH = destSpriteWorld->mainSWGDH;
  463.     
  464.     saveState = HGetState((Handle)cIconH);
  465.     HLock((Handle)cIconH);
  466.  
  467.     maskBitMap.rowBytes = (**cIconH).iconMask.rowBytes;
  468.     maskBitMap.bounds = (**cIconH).iconMask.bounds;
  469.     maskBitMap.baseAddr = (Ptr)(**cIconH).iconMaskData;
  470.     
  471.     if ( (**((**theGDH).gdPMap)).pixelSize == depth )
  472.         err = NewGWorld( &tempGWorldP, depth, &maskBitMap.bounds, nil, theGDH, noNewDevice );
  473.     else
  474.         err = NewGWorld( &tempGWorldP, depth, &maskBitMap.bounds, nil, nil, 0 );
  475.                 
  476.     if (err == noErr)
  477.     {    
  478.         SetGWorld(tempGWorldP, NULL);
  479.         
  480.         (void)LockPixels( GetGWorldPixMap(tempGWorldP) );
  481.         CopyBits(&maskBitMap, 
  482.             (BitMap*)*GetGWorldPixMap( tempGWorldP ),
  483.             &maskBitMap.bounds, 
  484.             &maskBitMap.bounds,
  485.             srcCopy, 
  486.             nil);        
  487.         UnlockPixels( GetGWorldPixMap(tempGWorldP) );
  488.         
  489.         *maskGWorldP = tempGWorldP;
  490.     }
  491.  
  492.     SetGWorld(saveGWorld, saveGDevice);
  493.  
  494.     HSetState((Handle)cIconH, saveState);
  495.  
  496.     SWSetStickyIfError( err );
  497.     return err;
  498. }
  499.  
  500. #pragma mark -
  501.  
  502. ///--------------------------------------------------------------------------------------
  503. //    SWInvertGWorld - inverts a GWorld's image. This is used to invert B&W masks.
  504. ///--------------------------------------------------------------------------------------
  505.  
  506. SW_FUNC void SWInvertGWorld(
  507.     GWorldPtr gWorldP)
  508. {
  509.     SWInvertRect(gWorldP, &gWorldP->portRect);
  510. }
  511.  
  512.  
  513. ///--------------------------------------------------------------------------------------
  514. //    SWInvertRect - inverts a portion of a GWorld. Called by SWUpdateFrameMasks  
  515. //    and SWInvertGWorld.
  516. ///--------------------------------------------------------------------------------------
  517.  
  518. SW_FUNC void SWInvertRect(
  519.     GWorldPtr gWorldP,
  520.     RectPtr    rectP)
  521. {
  522.     PixMapHandle    pixMapH;
  523.     GWorldFlags        pixelsState;
  524.     GWorldPtr        saveGWorld;
  525.     GDHandle        saveDevice;
  526.  
  527.     pixMapH = GetGWorldPixMap( gWorldP );
  528.     pixelsState = GetPixelsState( pixMapH );
  529.     (void)LockPixels( pixMapH );
  530.     
  531.     GetGWorld( &saveGWorld, &saveDevice);
  532.     SetGWorld(gWorldP, (GDHandle) NULL);
  533.     
  534.     InvertRect(rectP);
  535.     
  536.     SetGWorld( saveGWorld, saveDevice);
  537.     SetPixelsState( pixMapH, pixelsState );
  538. }
  539.  
  540.  
  541. ///--------------------------------------------------------------------------------------
  542. //    SWCopyGWorlds - copies srcGWorldP into dstGWorldP.
  543. ///--------------------------------------------------------------------------------------
  544.  
  545. SW_FUNC void SWCopyGWorlds( GWorldPtr srcGWorldP, GWorldPtr dstGWorldP )
  546. {
  547.     PixMapHandle    srcPixMapH;
  548.     PixMapHandle    dstPixMapH;
  549.     GWorldFlags        srcPixelsState;
  550.     GWorldFlags        dstPixelsState;
  551.     GWorldPtr        saveGWorld;
  552.     GDHandle        saveDevice;
  553.     
  554.     srcPixMapH = GetGWorldPixMap( srcGWorldP );
  555.     dstPixMapH = GetGWorldPixMap( dstGWorldP );
  556.     
  557.     srcPixelsState = GetPixelsState( srcPixMapH );
  558.     dstPixelsState = GetPixelsState( dstPixMapH );
  559.     (void) LockPixels( srcPixMapH );
  560.     (void) LockPixels( dstPixMapH );
  561.     
  562.     GetGWorld( &saveGWorld, &saveDevice);
  563.     SetGWorld(dstGWorldP, (GDHandle) NULL);
  564.     
  565.     CopyBits( (BitMap*)*srcPixMapH, (BitMap*)*dstPixMapH, 
  566.         &srcGWorldP->portRect, &dstGWorldP->portRect, srcCopy, (RgnHandle) NULL );
  567.         
  568.     SetGWorld( saveGWorld, saveDevice);
  569.  
  570.     SetPixelsState( srcPixMapH, srcPixelsState );
  571.     SetPixelsState( dstPixMapH, dstPixelsState );
  572. }
  573.  
  574.  
  575. ///--------------------------------------------------------------------------------------
  576. //    SWFlipPixelsHorizontally - mirrors part of a gworld horizontally
  577. //    Works in any depth, but is slow in depths below 8-bits.
  578. ///--------------------------------------------------------------------------------------
  579.  
  580. SW_FUNC void SWFlipPixelsHorizontally(GWorldPtr dstGWorldP, RectPtr rectP)
  581. {
  582.     Ptr                baseAddr,row;
  583.     UInt32            rowBytes;
  584.     Rect            bounds;
  585.     int                 width,height;
  586.     int                x,y,depth;
  587.     GWorldFlags        state;
  588.     PixMapHandle    pixMapHdl;
  589.     
  590.     pixMapHdl = GetGWorldPixMap( dstGWorldP );
  591.     
  592.     state = GetPixelsState(pixMapHdl);
  593.     (void) LockPixels(pixMapHdl);
  594.  
  595.     depth = (**pixMapHdl).pixelSize;
  596.     if ( rectP == NULL )
  597.         bounds = (**pixMapHdl).bounds;
  598.     else
  599.         bounds = *rectP;
  600.     
  601.     width = bounds.right - bounds.left;
  602.     height = bounds.bottom - bounds.top;
  603.     
  604.     START_32_BIT_MODE
  605.  
  606.     baseAddr = SWGetPixBaseAddr(pixMapHdl);
  607.     rowBytes = SWGetPixRowBytes(pixMapHdl);
  608.     
  609.     baseAddr += bounds.top * rowBytes;
  610.     baseAddr += (bounds.left * depth) >> 3;
  611.     
  612.     row = baseAddr;
  613.         
  614.     switch ( depth ) // bits per pixel
  615.     {
  616.         case 1:
  617.         {
  618.             Boolean        pixel1,pixel2;
  619.             int            x2;
  620.             
  621.             for ( y = 0; y < height; y++ )
  622.             {
  623.                 for ( x = 0, x2 = (width-1); x < (width >> 1); x++, x2-- )
  624.                 {
  625.                     pixel1 = BitTst(row,x);
  626.                     pixel2 = BitTst(row,x2);
  627.                 
  628.                     pixel1 ? BitSet(row,x2) : BitClr(row,x2);
  629.                     pixel2 ? BitSet(row,x ) : BitClr(row,x );
  630.                 }
  631.                 row += rowBytes;
  632.             }
  633.             break;
  634.         }
  635.         case 2:
  636.         case 4:
  637.         {
  638.             RGBColor    color1,color2;
  639.             int            x2;
  640.             GWorldPtr    saveGWorld;
  641.             GDHandle    saveGDevice;
  642.             
  643.             GetGWorld( &saveGWorld, &saveGDevice );
  644.             SetGWorld( dstGWorldP, (GDHandle) NULL );
  645.             
  646.             for ( y = 0; y < height; y++ )
  647.             {
  648.                 for ( x = 0, x2 = (width-1); x < (width >> 1); x++, x2-- )
  649.                 {
  650.                     GetCPixel(x ,y, &color1);
  651.                     GetCPixel(x2,y, &color2);
  652.                     
  653.                     SetCPixel(x2,y, &color1);
  654.                     SetCPixel(x ,y, &color2);
  655.                 }
  656.             }
  657.             
  658.             SetGWorld( saveGWorld, saveGDevice );
  659.             
  660.             break;
  661.         }
  662.         case 8:
  663.         {
  664.             UInt8    *ptr1,*ptr2,temp;    
  665.  
  666.             for ( y = 0; y < height; y++ )
  667.             {
  668.                 ptr1 = (UInt8 *) row;
  669.                 ptr2 = ptr1 + width;
  670.                 for ( x = 0; x < (width >> 1); x++ )
  671.                 {
  672.                     temp = *--ptr2;
  673.                     *ptr2 = *ptr1;
  674.                     *ptr1++ = temp;
  675.                 }
  676.                 row += rowBytes;
  677.             }
  678.             break;
  679.         }
  680.         case 16:
  681.         {
  682.             UInt16    *ptr1,*ptr2,temp;    
  683.  
  684.             for ( y = 0; y < height; y++ )
  685.             {
  686.                 ptr1 = (UInt16 *) row;
  687.                 ptr2 = ptr1 + width;
  688.                 for ( x = 0; x < (width >> 1); x++ )
  689.                 {
  690.                     temp = *--ptr2;
  691.                     *ptr2 = *ptr1;
  692.                     *ptr1++ = temp;
  693.                 }
  694.                 row += rowBytes;
  695.             }
  696.             break;
  697.         }
  698.         case 32:
  699.         {
  700.             UInt32    *ptr1,*ptr2,temp;    
  701.  
  702.             for ( y = 0; y < height; y++ )
  703.             {
  704.                 ptr1 = (UInt32 *) row;
  705.                 ptr2 = ptr1 + width;
  706.                 for ( x = 0; x < (width >> 1); x++ )
  707.                 {
  708.                     temp = *--ptr2;
  709.                     *ptr2 = *ptr1;
  710.                     *ptr1++ = temp;
  711.                 }
  712.                 row += rowBytes;
  713.             }
  714.             break;
  715.         }
  716.         default:
  717.             // unknown pixel depth
  718.             break;
  719.     }
  720.  
  721.     END_32_BIT_MODE
  722.  
  723.     SetPixelsState(pixMapHdl,state);
  724. }
  725.  
  726.  
  727. ///--------------------------------------------------------------------------------------
  728. //    SWFlipPixelsVertically - mirrors part of a gworld vertically
  729. //    Works in any depth, but is slow in depths below 8-bits.
  730. ///--------------------------------------------------------------------------------------
  731.  
  732. SW_FUNC void SWFlipPixelsVertically(GWorldPtr dstGWorldP, RectPtr rectP)
  733. {
  734.     Ptr                baseAddr,row1,row2;
  735.     UInt32            rowBytes;
  736.     Rect            bounds;
  737.     int             width,height;
  738.     int                x,y,depth;
  739.     GWorldFlags        state;
  740.     PixMapHandle    pixMapHdl;
  741.     
  742.     pixMapHdl = GetGWorldPixMap( dstGWorldP );
  743.     
  744.     state = GetPixelsState(pixMapHdl);
  745.     (void) LockPixels(pixMapHdl);
  746.  
  747.     depth = (**pixMapHdl).pixelSize;
  748.     if ( rectP == NULL )
  749.         bounds = (**pixMapHdl).bounds;
  750.     else
  751.         bounds = *rectP;
  752.     
  753.     width = bounds.right - bounds.left;
  754.     height = bounds.bottom - bounds.top;
  755.     
  756.     START_32_BIT_MODE
  757.  
  758.     baseAddr = SWGetPixBaseAddr(pixMapHdl);
  759.     rowBytes = SWGetPixRowBytes(pixMapHdl);
  760.     
  761.     baseAddr += bounds.top * rowBytes;
  762.     baseAddr += (bounds.left * depth) >> 3;
  763.     
  764.     row1 = baseAddr;
  765.     row2 = baseAddr + (height-1) * rowBytes;
  766.         
  767.     switch ( depth ) // bits per pixel
  768.     {
  769.         case 1:
  770.         {
  771.             Boolean        pixel1,pixel2;
  772.             
  773.             for ( y = 0; y < (height >> 1); y++ )
  774.             {
  775.                 for ( x = 0; x < width; x++ )
  776.                 {
  777.                     pixel1 = BitTst(row1,x);
  778.                     pixel2 = BitTst(row2,x);
  779.                     
  780.                     pixel1 ? BitSet(row2,x) : BitClr(row2,x);
  781.                     pixel2 ? BitSet(row1,x) : BitClr(row1,x);
  782.                 }
  783.                 row1 += rowBytes;
  784.                 row2 -= rowBytes;
  785.             }
  786.             break;
  787.         }
  788.         case 2:
  789.         case 4:
  790.         {
  791.             RGBColor    color1,color2;
  792.             int            y2;
  793.             GWorldPtr    saveGWorld;
  794.             GDHandle    saveGDevice;
  795.             
  796.             GetGWorld( &saveGWorld, &saveGDevice );
  797.             SetGWorld( dstGWorldP, (GDHandle) NULL );
  798.         
  799.             for ( y = 0, y2 = (height-1); y < (height >> 1); y++, y2-- )
  800.             {
  801.                 for ( x = 0; x < width; x++ )
  802.                 {
  803.                     GetCPixel(x,y , &color1);
  804.                     GetCPixel(x,y2, &color2);
  805.                 
  806.                     SetCPixel(x,y2, &color1);
  807.                     SetCPixel(x,y , &color2);
  808.                 }
  809.             }
  810.             
  811.             SetGWorld( saveGWorld, saveGDevice );
  812.             
  813.             break;
  814.         }
  815.         case 8:
  816.         {
  817.             UInt8    *ptr1,*ptr2,temp;    
  818.  
  819.             for ( y = 0; y < (height >> 1); y++ )
  820.             {
  821.                 ptr1 = (UInt8 *) row1;
  822.                 ptr2 = (UInt8 *) row2;
  823.                 for ( x = 0; x < width; x++ )
  824.                 {
  825.                     temp = *ptr1;
  826.                     *ptr1++ = *ptr2;
  827.                     *ptr2++ = temp;
  828.                 }
  829.                 row1 += rowBytes;
  830.                 row2 -= rowBytes;
  831.             }
  832.             break;
  833.         }
  834.         case 16:
  835.         {
  836.             UInt16    *ptr1,*ptr2,temp;    
  837.  
  838.             for ( y = 0; y < (height >> 1); y++ )
  839.             {
  840.                 ptr1 = (UInt16 *) row1;
  841.                 ptr2 = (UInt16 *) row2;
  842.                 for ( x = 0; x < width; x++ )
  843.                 {
  844.                     temp = *ptr1;
  845.                     *ptr1++ = *ptr2;
  846.                     *ptr2++ = temp;
  847.                 }
  848.                 row1 += rowBytes;
  849.                 row2 -= rowBytes;
  850.             }
  851.             break;
  852.         }
  853.         case 32:
  854.         {
  855.             UInt32    *ptr1,*ptr2,temp;    
  856.  
  857.             for ( y = 0; y < (height >> 1); y++ )
  858.             {
  859.                 ptr1 = (UInt32 *) row1;
  860.                 ptr2 = (UInt32 *) row2;
  861.                 for ( x = 0; x < width; x++ )
  862.                 {
  863.                     temp = *ptr1;
  864.                     *ptr1++ = *ptr2;
  865.                     *ptr2++ = temp;
  866.                 }
  867.                 row1 += rowBytes;
  868.                 row2 -= rowBytes;
  869.             }
  870.             break;
  871.         }
  872.         default:
  873.             // unknown pixel depth
  874.             break;
  875.     }
  876.  
  877.     END_32_BIT_MODE
  878.  
  879.     SetPixelsState(pixMapHdl,state);
  880. }
  881.  
  882. #pragma mark -
  883.  
  884. ///-------------------------------------------------------------------------------------
  885. //    SWSetTransparentColor - allows you to set the background, or unmasked color
  886. //    of a sprite to a color other than white. Important: the sprite's background color
  887. //    MUST match the color you use with gSWTransparentColor, or the Sprite won't load correctly.
  888. ///--------------------------------------------------------------------------------------
  889.  
  890. SW_FUNC void SWSetTransparentColor(RGBColor *RGB)
  891. {
  892.     gSWTransparentColor = *RGB;
  893. }
  894.  
  895.  
  896. ///--------------------------------------------------------------------------------------
  897. //    ComputePixelValues
  898. ///--------------------------------------------------------------------------------------
  899.  
  900. void ComputePixelValues( short pixelSize )
  901. {
  902.     if ( pixelSize <= 8 )
  903.     {
  904.             // Indexed Color
  905.         SWMaskedRGBValue = 0x0000;        // black, becomes last index : all ones
  906.         SWTransparentRGBValue = 0xFFFF;    // white, becomes first index : all zeros
  907.     }
  908.     else
  909.     {
  910.             // Direct Color
  911.         SWMaskedRGBValue = 0xFFFF;        // white, is RGB : all ones
  912.         SWTransparentRGBValue = 0x0000;    // black, is RGB : all zeros
  913.     }
  914. }
  915.  
  916.  
  917. ///--------------------------------------------------------------------------------------
  918. //    SWCreatePixelMaskFromGWorld - converts the image in pictureGWorld to a black and white 
  919. //      mask that is stored in maskGWorld.
  920. //  Portions having gSWTransparentColor will be cleared ("white"), others made solid ("black").
  921. //    This function doubles as a faster version of SWBlackenGWorld.
  922. //
  923. //    Note1:  the maskGWorld will be completely redrawn, so it can contain garbage
  924. //    Note2: this function handles unlocked GWorlds (locks them temporarily)
  925. //    Note3: both GWorlds must be the same depth
  926. //
  927. //         IMAGE -> MASK
  928. ///--------------------------------------------------------------------------------------
  929.  
  930. SW_FUNC OSErr SWCreatePixelMaskFromGWorld( GWorldPtr pictureGWorld, GWorldPtr maskGWorld, RectPtr rectP )
  931. {
  932.     UInt32            transparent;
  933.     GWorldPtr        saveGWorld;
  934.     GDHandle        saveDevice;
  935.     Ptr                baseAddr;
  936.     Ptr                maskAddr;
  937.     long            rowBytes;
  938.     long            width,height;
  939.     long            depth;
  940.     long            x,y;
  941.     unsigned short    transparentValue;
  942.     PixMapHandle    pictPix;
  943.     PixMapHandle    maskPix;
  944.     GWorldFlags        pictPixelsState;
  945.     GWorldFlags        maskPixelsState;
  946.     OSErr            err = noErr;
  947.     
  948.     pictPix = GetGWorldPixMap( pictureGWorld );
  949.     maskPix = GetGWorldPixMap( maskGWorld );
  950.     
  951.     SW_ASSERT( (**pictPix).pixelSize == (**maskPix).pixelSize );
  952.     
  953.     if ( rectP == NULL )
  954.         rectP = &pictureGWorld->portRect;
  955.         
  956.     width = rectP->right - rectP->left;
  957.     height = rectP->bottom - rectP->top;
  958.  
  959.     depth = (**pictPix).pixelSize;
  960.     ComputePixelValues(depth);
  961.     transparentValue = SWTransparentRGBValue;
  962.     
  963.         // Determine whether we need to fix the image's GWorld too,
  964.         // at the same time as creating the mask.
  965.     if (gSWTransparentColor.red != transparentValue ||
  966.         gSWTransparentColor.green != transparentValue ||
  967.         gSWTransparentColor.blue != transparentValue    )
  968.     {
  969.         return SWCreateMaskAndFixImage(pictureGWorld, maskGWorld, rectP);
  970.     }
  971.     
  972.         // This function won't work in depths lower than 8-bit, so we
  973.         // need to call the old SWBlackenGWorld in this case.
  974.     if (depth < 8)
  975.     {
  976.         SWCopyGWorlds(pictureGWorld, maskGWorld);
  977.         SWBlackenGWorld(maskGWorld);
  978.         if (depth <= 8 )
  979.             SWInvertGWorld(maskGWorld);
  980.         
  981.         return noErr;
  982.     }
  983.     
  984.     GetGWorld( &saveGWorld, &saveDevice);
  985.     
  986.     pictPixelsState = GetPixelsState( pictPix );
  987.     LockPixels( pictPix );
  988.     maskPixelsState = GetPixelsState( maskPix );
  989.     LockPixels( maskPix );
  990.     
  991.     SetGWorld( pictureGWorld, NULL);
  992.     transparent = Color2Index( &gSWTransparentColor );
  993.     
  994.     START_32_BIT_MODE
  995.  
  996.     baseAddr = SWGetPixBaseAddr(pictPix);
  997.     maskAddr = SWGetPixBaseAddr(maskPix);
  998.     rowBytes = SWGetPixRowBytes(pictPix);
  999.     
  1000.     baseAddr += rectP->top * rowBytes;
  1001.     baseAddr += (rectP->left * depth) >> 3;
  1002.     maskAddr += rectP->top * rowBytes;
  1003.     maskAddr += (rectP->left * depth) >> 3;
  1004.     rowBytes -= (width * depth) >> 3;
  1005.     
  1006.         // Copy from the image GWorld to the mask GWorld,
  1007.         // turning all non-white colors to black as we go.
  1008.     switch ( depth )
  1009.     {
  1010.         case 8:
  1011.             {
  1012.                 UInt8    *dst = (UInt8 *) baseAddr;
  1013.                 UInt8    *mask = (UInt8 *) maskAddr;
  1014.                 
  1015.                 for ( y = 0; y < height; y++ )
  1016.                 {
  1017.                     for ( x = 0; x < width; x++ )
  1018.                     {
  1019.                         if ( *dst++ == transparent )
  1020.                             *mask++ = kClear;
  1021.                         else
  1022.                             *mask++ = kSolid;
  1023.                     }
  1024.                     dst = (UInt8 *) ( (char *) dst + rowBytes );
  1025.                     mask = (UInt8 *) ( (char *) mask + rowBytes );
  1026.                 }
  1027.             }
  1028.             break;
  1029.         case 16:
  1030.             {
  1031.                 UInt16    *dst = (UInt16 *) baseAddr;
  1032.                 UInt16    *mask = (UInt16 *) maskAddr;
  1033.                 
  1034.                 transparent &= kAlphaMask16;
  1035.                 for ( y = 0; y < height; y++ )
  1036.                 {
  1037.                     for ( x = 0; x < width; x++ )
  1038.                     {
  1039.                         if ( (*dst++ & kAlphaMask16) == transparent )
  1040.                             *mask++ = kClear;
  1041.                         else
  1042.                             *mask++ = kSolid;
  1043.                     }
  1044.                     dst = (UInt16 *) ( (char *) dst + rowBytes );
  1045.                     mask = (UInt16 *) ( (char *) mask + rowBytes );
  1046.                 }
  1047.             }
  1048.             break;
  1049.         case 32:
  1050.             {
  1051.                 UInt32    *dst = (UInt32 *) baseAddr;
  1052.                 UInt32    *mask = (UInt32 *) maskAddr;
  1053.                 
  1054.                 transparent &= kAlphaMask32;
  1055.                 for ( y = 0; y < height; y++ )
  1056.                 {
  1057.                     for ( x = 0; x < width; x++ )
  1058.                     {
  1059.                         if ( (*dst++ & kAlphaMask32) == transparent )
  1060.                             *mask++ = kClear;
  1061.                         else
  1062.                             *mask++ = kSolid;
  1063.                     }
  1064.                     dst = (UInt32 *) ( (char *) dst + rowBytes );
  1065.                     mask = (UInt32 *) ( (char *) mask + rowBytes );
  1066.                 }
  1067.             }
  1068.             break;
  1069.         default:
  1070.             err = paramErr;
  1071.     }
  1072.  
  1073.     END_32_BIT_MODE
  1074.     
  1075.     SetGWorld( saveGWorld, saveDevice);
  1076.  
  1077.     SetPixelsState( pictPix, pictPixelsState );
  1078.     SetPixelsState( maskPix, maskPixelsState );
  1079.  
  1080.     return err;
  1081. }
  1082.  
  1083.  
  1084. ///--------------------------------------------------------------------------------------
  1085. //    SWFixImageGWorld - erase non-masked parts of the image, so that 16-bit Sprites
  1086. //        can use the real 16-bit blitters, rather than the partial-mask versions.
  1087. //  Unmasked portions will be cleared for the masking blitter, others left as-is.
  1088. //    While this function doubles as a faster version of SWWhitenGWorld, it is only 
  1089. //    called when loading Sprites in 16-bit or 32-bit that are not self-masking.
  1090. //
  1091. //    Note1: the unmasked parts will be completely erased, so they can contain garbage
  1092. //    Note2: this function handles unlocked GWorlds (locks them temporarily)
  1093. //
  1094. //         IMAGE <- MASK
  1095. //
  1096. //    Update: this function now also fixes the alpha channel of the mask, for pixel collisions
  1097. ///--------------------------------------------------------------------------------------
  1098.  
  1099. SW_FUNC OSErr SWFixImageGWorld( GWorldPtr pictureGWorld, GWorldPtr maskGWorld, RectPtr rectP )
  1100. {
  1101.     GWorldPtr        saveGWorld;
  1102.     GDHandle        saveDevice;
  1103.     Ptr                baseAddr;
  1104.     Ptr                maskAddr;
  1105.     long            rowBytes;
  1106.     long            width,height;
  1107.     long            depth;
  1108.     long            x,y;
  1109.     unsigned short    transparentValue;
  1110.     PixMapHandle    pictPix;
  1111.     PixMapHandle    maskPix;
  1112.     GWorldFlags        pictPixelsState;
  1113.     GWorldFlags        maskPixelsState;
  1114.     OSErr            err = noErr;
  1115.     
  1116.     pictPix = GetGWorldPixMap( pictureGWorld );
  1117.     maskPix = GetGWorldPixMap( maskGWorld );
  1118.     
  1119.     SW_ASSERT( (**pictPix).pixelSize == (**maskPix).pixelSize );
  1120.  
  1121.     if ( rectP == NULL )
  1122.         rectP = &pictureGWorld->portRect;
  1123.         
  1124.     width = rectP->right - rectP->left;
  1125.     height = rectP->bottom - rectP->top;
  1126.     
  1127.     depth = (**pictPix).pixelSize;
  1128.     ComputePixelValues(depth);
  1129.     transparentValue = SWTransparentRGBValue;
  1130.  
  1131. /*    // afb: Removed this, since we might need to fix the MASK image
  1132.  
  1133.         // Determine whether we need to fix this GWorld's image at all?
  1134.     if (gSWTransparentColor.red == transparentValue &&
  1135.         gSWTransparentColor.green == transparentValue &&
  1136.         gSWTransparentColor.blue == transparentValue    )
  1137.     {
  1138.         return noErr;
  1139.     }
  1140. */
  1141.         // This function won't work in depths lower than 8-bit, so we
  1142.         // need to call the old SWWhitenGWorld in this case.
  1143.     if ( depth <= 8 )
  1144.     {
  1145.         SWWhitenGWorld(pictureGWorld);
  1146.         return noErr;
  1147.     }
  1148.     
  1149.     GetGWorld( &saveGWorld, &saveDevice);
  1150.  
  1151.     pictPixelsState = GetPixelsState( pictPix );
  1152.     LockPixels( pictPix );
  1153.     maskPixelsState = GetPixelsState( maskPix );
  1154.     LockPixels( maskPix );
  1155.     
  1156.     START_32_BIT_MODE
  1157.     
  1158.     baseAddr = SWGetPixBaseAddr(pictPix);
  1159.     maskAddr = SWGetPixBaseAddr(maskPix);
  1160.     rowBytes = SWGetPixRowBytes(pictPix);
  1161.     
  1162.     baseAddr += rectP->top * rowBytes;
  1163.     baseAddr += (rectP->left * depth) >> 3;
  1164.     maskAddr += rectP->top * rowBytes;
  1165.     maskAddr += (rectP->left * depth) >> 3;
  1166.     rowBytes -= (width * depth) >> 3;
  1167.     
  1168.         // Copy from the mask GWorld to the image GWorld,
  1169.         // but only clearing all the non-masked sections.
  1170.     switch ( depth )
  1171.     {
  1172.         case 8:
  1173.             {
  1174.                 UInt8    *dst = (UInt8 *) baseAddr;
  1175.                 UInt8    *mask = (UInt8 *) maskAddr;
  1176.                 
  1177.                 for ( y = 0; y < height; y++ )
  1178.                 {
  1179.                     for ( x = 0; x < width; x++ )
  1180.                     {
  1181.                         if ( *mask )    
  1182.                         {
  1183.                             *dst++ = 0;
  1184.                             *mask++ = kClear;
  1185.                         }
  1186.                         else
  1187.                         {
  1188.                             dst++;
  1189.                             *mask++ = kSolid;
  1190.                         }
  1191.                     }
  1192.                     dst = (UInt8 *) ( (char *) dst + rowBytes );
  1193.                     mask = (UInt8 *) ( (char *) mask + rowBytes );
  1194.                 }
  1195.             }
  1196.             break;
  1197.         case 16:
  1198.             {
  1199.                 UInt16    *dst = (UInt16 *) baseAddr;
  1200.                 UInt16    *mask = (UInt16 *) maskAddr;
  1201.                 
  1202.                 for ( y = 0; y < height; y++ )
  1203.                 {
  1204.                     for ( x = 0; x < width; x++ )
  1205.                     {
  1206.                         if ( *mask )    
  1207.                         {
  1208.                             *dst++ = 0;
  1209.                             *mask++ = kClear;
  1210.                         }
  1211.                         else
  1212.                         {
  1213.                             dst++;
  1214.                             *mask++ = kSolid;
  1215.                         }
  1216.                     }
  1217.                     dst = (UInt16 *) ( (char *) dst + rowBytes );
  1218.                     mask = (UInt16 *) ( (char *) mask + rowBytes );
  1219.                 }
  1220.             }
  1221.             break;
  1222.         case 32:
  1223.             {
  1224.                 UInt32    *dst = (UInt32 *) baseAddr;
  1225.                 UInt32    *mask = (UInt32 *) maskAddr;
  1226.                 
  1227.                 for ( y = 0; y < height; y++ )
  1228.                 {
  1229.                     for ( x = 0; x < width; x++ )
  1230.                     {            
  1231.                         if ( *mask )    
  1232.                         {
  1233.                             *dst++ = 0;
  1234.                             *mask++ = kClear;
  1235.                         }
  1236.                         else
  1237.                         {
  1238.                             dst++;
  1239.                             *mask++ = kSolid;
  1240.                         }
  1241.                     }
  1242.                     dst = (UInt32 *) ( (char *) dst + rowBytes );
  1243.                     mask = (UInt32 *) ( (char *) mask + rowBytes );
  1244.                 }
  1245.             }
  1246.             break;
  1247.         default:
  1248.             err = paramErr;
  1249.     }
  1250.  
  1251.     END_32_BIT_MODE
  1252.     
  1253.     SetGWorld( saveGWorld, saveDevice);
  1254.  
  1255.     SetPixelsState( pictPix, pictPixelsState );
  1256.     SetPixelsState( maskPix, maskPixelsState );
  1257.  
  1258.     return err;
  1259. }
  1260.  
  1261.  
  1262. ///--------------------------------------------------------------------------------------
  1263. //    SWCreateMaskAndFixImage - this is equal to first calling SWCreateMask and then SWFixImage.
  1264. //        Calling this function is faster (up to twice) than calling them both separately. 
  1265. //
  1266. //        IMAGE -> MASK, MASK -> IMAGE
  1267. ///--------------------------------------------------------------------------------------
  1268.  
  1269. SW_FUNC OSErr SWCreateMaskAndFixImage( GWorldPtr pictureGWorld, GWorldPtr maskGWorld, RectPtr rectP )
  1270. {
  1271.     UInt32            transparent;
  1272.     GWorldPtr        saveGWorld;
  1273.     GDHandle        saveDevice;
  1274.     Ptr                baseAddr;
  1275.     Ptr                maskAddr;
  1276.     long            rowBytes;
  1277.     long            width,height;
  1278.     long            depth;
  1279.     long            x,y;
  1280.     unsigned short    transparentValue;
  1281.     PixMapHandle    pictPix;
  1282.     PixMapHandle    maskPix;
  1283.     GWorldFlags        pictPixelsState;
  1284.     GWorldFlags        maskPixelsState;
  1285.  
  1286.     pictPix = GetGWorldPixMap( pictureGWorld );
  1287.     maskPix = GetGWorldPixMap( maskGWorld );
  1288.     
  1289.     SW_ASSERT( (**pictPix).pixelSize == (**maskPix).pixelSize );
  1290.     
  1291.     if ( rectP == NULL )
  1292.         rectP = &pictureGWorld->portRect;
  1293.         
  1294.     width = rectP->right - rectP->left;
  1295.     height = rectP->bottom - rectP->top;
  1296.  
  1297.     depth = (**pictPix).pixelSize;
  1298.     ComputePixelValues(depth);
  1299.     transparentValue = SWTransparentRGBValue;
  1300.  
  1301.         // This function won't work in depths lower than 8-bit, so we
  1302.         // need to call the old SWBlackenGWorld in this case.
  1303.     if (    depth < 8     )
  1304.     {
  1305.         SWCopyGWorlds(pictureGWorld, maskGWorld);
  1306.         SWBlackenGWorld(maskGWorld);
  1307.         if (depth <= 8 )
  1308.             SWInvertGWorld(maskGWorld);
  1309.         SWWhitenGWorld(pictureGWorld);
  1310.         
  1311.         return noErr;
  1312.     }
  1313.     
  1314.     GetGWorld( &saveGWorld, &saveDevice);
  1315.     
  1316.     pictPixelsState = GetPixelsState( pictPix );
  1317.     LockPixels( pictPix );
  1318.     maskPixelsState = GetPixelsState( maskPix );
  1319.     LockPixels( maskPix );
  1320.  
  1321.     SetGWorld( pictureGWorld, (GDHandle) NULL);
  1322.     transparent = Color2Index( &gSWTransparentColor );
  1323.     
  1324.     START_32_BIT_MODE
  1325.  
  1326.     baseAddr = SWGetPixBaseAddr(pictPix);
  1327.     maskAddr = SWGetPixBaseAddr(maskPix);
  1328.     rowBytes = SWGetPixRowBytes(pictPix);
  1329.  
  1330.     baseAddr += rectP->top * rowBytes;
  1331.     baseAddr += (rectP->left * depth) >> 3;
  1332.     maskAddr += rectP->top * rowBytes;
  1333.     maskAddr += (rectP->left * depth) >> 3;
  1334.     rowBytes -= (width * depth) >> 3;
  1335.     
  1336.     switch ( depth )
  1337.     {
  1338.         case 8:
  1339.             {
  1340.                 UInt8    *dst = (UInt8 *) baseAddr;
  1341.                 UInt8    *mask = (UInt8 *) maskAddr;
  1342.                 
  1343.                 for ( y = 0; y < height; y++ )
  1344.                 {
  1345.                     for ( x = 0; x < width; x++ )
  1346.                     {
  1347.                         if ( *dst == transparent )
  1348.                         {
  1349.                             *dst++ = 0;
  1350.                             *mask++ = kClear;
  1351.                         }
  1352.                         else
  1353.                         {
  1354.                             dst++;
  1355.                             *mask++ = kSolid;
  1356.                         }
  1357.                     }
  1358.                     dst = (UInt8 *) ( (char *) dst + rowBytes );
  1359.                     mask = (UInt8 *) ( (char *) mask + rowBytes );
  1360.                 }
  1361.             }
  1362.             break;
  1363.         case 16:
  1364.             {
  1365.                 UInt16    *dst = (UInt16 *) baseAddr;
  1366.                 UInt16    *mask = (UInt16 *) maskAddr;
  1367.                 
  1368.                 transparent &= kAlphaMask16;
  1369.                 for ( y = 0; y < height; y++ )
  1370.                 {
  1371.                     for ( x = 0; x < width; x++ )
  1372.                     {
  1373.                         if ( (*dst & kAlphaMask16) == transparent )
  1374.                         {
  1375.                             *dst++ = 0;
  1376.                             *mask++ = kClear;
  1377.                         }
  1378.                         else
  1379.                         {
  1380.                             dst++;
  1381.                             *mask++ = kSolid;
  1382.                         }
  1383.                     }
  1384.                     dst = (UInt16 *) ( (char *) dst + rowBytes );
  1385.                     mask = (UInt16 *) ( (char *) mask + rowBytes );
  1386.                 }
  1387.             }
  1388.             break;
  1389.         case 32:
  1390.             {
  1391.                 UInt32    *dst = (UInt32 *) baseAddr;
  1392.                 UInt32    *mask = (UInt32 *) maskAddr;
  1393.                 
  1394.                 transparent &= kAlphaMask32;
  1395.                 for ( y = 0; y < height; y++ )
  1396.                 {
  1397.                     for ( x = 0; x < width; x++ )
  1398.                     {
  1399.                         if ( (*dst & kAlphaMask32) == transparent )
  1400.                         {
  1401.                             *dst++ = 0;
  1402.                             *mask++ = kClear;
  1403.                         }
  1404.                         else
  1405.                         {
  1406.                             dst++;
  1407.                             *mask++ = kSolid;
  1408.                         }
  1409.                     }
  1410.                     dst = (UInt32 *) ( (char *) dst + rowBytes );
  1411.                     mask = (UInt32 *) ( (char *) mask + rowBytes );
  1412.                 }
  1413.             }
  1414.             break;
  1415.         default:
  1416.             return paramErr;
  1417.     }
  1418.  
  1419.     END_32_BIT_MODE
  1420.     
  1421.     SetGWorld( saveGWorld, saveDevice);
  1422.  
  1423.     SetPixelsState( pictPix, pictPixelsState );
  1424.     SetPixelsState( maskPix, maskPixelsState );
  1425.  
  1426.     return noErr;
  1427. }
  1428.  
  1429.  
  1430. #pragma mark -
  1431.  
  1432.     // ColorSearchProc for SWBlackenGWorld
  1433. static pascal Boolean blackenColorSearch( RGBColor *RGB, long *position );
  1434.  
  1435. ///--------------------------------------------------------------------------------------
  1436. //    SWBlackenGWorld - converts all non-gSWTransparentColor pixels to black, all others
  1437. //  to white (transparent). Since this has been replaced with SWCreatePixelMaskFromGWorld,
  1438. //    this function is only called when the depth is lower than 8-bits.
  1439. ///--------------------------------------------------------------------------------------
  1440.  
  1441. SW_FUNC OSErr SWBlackenGWorld( GWorldPtr oldGWorld )
  1442. {
  1443.     GWorldPtr            saveGWorld, newGWld;
  1444.     GDHandle            saveGDH;
  1445.     Rect                gwldRect;
  1446.     GWorldFlags            pixelState;
  1447.     ColorSearchUPP        blackenColSearchUPP;
  1448.     PixMapHandle        newPix;
  1449.     PixMapHandle        oldPix;
  1450.     OSErr                err;
  1451.         
  1452.     GetGWorld( &saveGWorld, &saveGDH );
  1453.     
  1454.     oldPix = GetGWorldPixMap(oldGWorld);
  1455.         
  1456.     gwldRect = oldGWorld->portRect;
  1457.     pixelState = GetPixelsState( oldPix );
  1458.     
  1459.     err = NewGWorld(&newGWld, 1, &gwldRect, nil, nil, 0 );
  1460.     
  1461.     if ( err == noErr )
  1462.     {
  1463.             // First, copy from the color GWorld to the 1-bit GWorld, turning all
  1464.             // non-white colors to black as we go.
  1465.         newPix = GetGWorldPixMap(newGWld);
  1466.         (void)LockPixels( newPix );
  1467.         (void)LockPixels( oldPix );
  1468.         SetGWorld( oldGWorld, nil );
  1469.         ForeColor(blackColor);
  1470.         BackColor(whiteColor);
  1471.         SetGWorld( newGWld, nil );
  1472.         blackenColSearchUPP = NewColorSearchProc( blackenColorSearch );
  1473.         AddSearch( blackenColSearchUPP );
  1474.         ComputePixelValues( (**oldPix).pixelSize );
  1475.         CopyBits (
  1476.             (BitMap*) *oldPix,
  1477.             (BitMap*) *newPix,
  1478.             &gwldRect, 
  1479.             &gwldRect, 
  1480.             srcCopy, 
  1481.             nil);
  1482.         DelSearch( blackenColSearchUPP );
  1483.         DisposeRoutineDescriptor( blackenColSearchUPP );
  1484.         
  1485.             // Next, copy the result back into the original GWorld.
  1486.         SetGWorld( oldGWorld, nil );
  1487.         CopyBits (
  1488.             (BitMap*) *newPix,
  1489.             (BitMap*) *oldPix,
  1490.             &gwldRect, 
  1491.             &gwldRect, 
  1492.             srcCopy, 
  1493.             nil);
  1494.         
  1495.         SetPixelsState( oldGWorld->portPixMap, pixelState );
  1496.         DisposeGWorld( newGWld );
  1497.     }
  1498.     
  1499.     SetGWorld( saveGWorld, saveGDH );
  1500.     
  1501.     SWSetStickyIfError( err );
  1502.     return err;
  1503. }
  1504.  
  1505.  
  1506.  
  1507. ///--------------------------------------------------------------------------------------
  1508. //    blackenColorSearch
  1509. ///--------------------------------------------------------------------------------------
  1510.  
  1511. pascal Boolean blackenColorSearch( RGBColor *RGB, long* position )
  1512. {
  1513.     #pragma unused(position)
  1514.     
  1515.         // Convert transparent pixels to "white", and the others to "black"
  1516.     if (    RGB->red == gSWTransparentColor.red        &&
  1517.             RGB->green == gSWTransparentColor.green    &&
  1518.             RGB->blue == gSWTransparentColor.blue    )
  1519.     {
  1520.         RGB->red = RGB->green = RGB->blue = SWTransparentRGBValue;    // transparent (white, 0)
  1521.     }
  1522.     else
  1523.     {
  1524.         RGB->red = RGB->green = RGB->blue = SWMaskedRGBValue;        // masked (black, 1)
  1525.     }
  1526.     
  1527.     return ( false );
  1528. }
  1529.  
  1530.  
  1531. ///--------------------------------------------------------------------------------------
  1532. //    SWCreateRegionMaskFromGWorld - converts the image in pictureGWorld to a region mask
  1533. //
  1534. //    useful for creating a region mask when there is no pixel mask
  1535. //    pictureGWorld does NOT have to be blackened before calling this function
  1536. ///--------------------------------------------------------------------------------------
  1537.  
  1538. SW_FUNC OSErr SWCreateRegionMaskFromGWorld( GWorldPtr pictureGWorld,
  1539.     Rect *pictureRect, RgnHandle maskRegion )
  1540. {
  1541.     GWorldPtr            saveGWorld, tempGWld;
  1542.     GDHandle            saveGDH;
  1543.     GWorldFlags            pixelState;
  1544.     ColorSearchUPP        blackenColSearchUPP;
  1545.     PixMapHandle        tempPix;
  1546.     PixMapHandle        oldPix;
  1547.     OSErr                err;
  1548.     Rect                gwldRect;
  1549.         
  1550.     GetGWorld( &saveGWorld, &saveGDH );
  1551.     
  1552.     gwldRect = *pictureRect;
  1553.     OffsetRect(&gwldRect, -gwldRect.left, -gwldRect.top);
  1554.         
  1555.     err = NewGWorld(&tempGWld, 1, &gwldRect, nil, nil, 0 );
  1556.     
  1557.     if ( err == noErr )
  1558.     {
  1559.         oldPix = GetGWorldPixMap(pictureGWorld);
  1560.         pixelState = GetPixelsState( oldPix );
  1561.  
  1562.             // we want a mask compatible with BitMapToRegion (black is solid)
  1563.         ComputePixelValues( 8 );
  1564.         
  1565.             // First, copy from the color GWorld to the 1-bit GWorld,
  1566.             // turning everything to black and white as we go.
  1567.         tempPix = GetGWorldPixMap(tempGWld);
  1568.         (void)LockPixels( tempPix );
  1569.         (void)LockPixels( oldPix );
  1570.         SetGWorld( pictureGWorld, nil );
  1571.         ForeColor(blackColor);
  1572.         BackColor(whiteColor);
  1573.         SetGWorld( tempGWld, nil );
  1574.         ForeColor(blackColor);
  1575.         BackColor(whiteColor);
  1576.         blackenColSearchUPP = NewColorSearchProc( blackenColorSearch );
  1577.         AddSearch( blackenColSearchUPP );
  1578.         CopyBits (
  1579.             (BitMap*) *oldPix,
  1580.             (BitMap*) *tempPix,
  1581.             &gwldRect, 
  1582.             &gwldRect, 
  1583.             srcCopy, 
  1584.             nil);
  1585.         DelSearch( blackenColSearchUPP );
  1586.         DisposeRoutineDescriptor( blackenColSearchUPP );
  1587.         
  1588.             // Then, update the region mask
  1589.         err = BitMapToRegion( maskRegion, (BitMap*) *tempPix);
  1590.         
  1591.         DisposeGWorld( tempGWld );
  1592.     
  1593.         SetPixelsState( pictureGWorld->portPixMap, pixelState );
  1594.     }
  1595.     
  1596.     SetGWorld( saveGWorld, saveGDH );
  1597.     
  1598.     SWSetStickyIfError( err );
  1599.     return err;
  1600. }
  1601.  
  1602. #pragma mark -
  1603.  
  1604.     // ColorSearchProc for SWWhitenGWorld
  1605. static pascal Boolean whitenColorSearch( RGBColor *RGB, long *position );
  1606.  
  1607. ///--------------------------------------------------------------------------------------
  1608. //    SWWhitenGWorld - changes all pixels in the GWorld matching gSWTransparentColor to white.
  1609. //    This function, along with SWSetTransparentColor, allows you to load self-masking sprites
  1610. //    without requiring the "transparent" color to be white. (With an additional delay, 
  1611. //    that is.) Since this has been replace with SWFixImageGWorld, this is only used when
  1612. //    the depth is less than 8-bits.
  1613. ///--------------------------------------------------------------------------------------
  1614.  
  1615. SW_FUNC OSErr SWWhitenGWorld( GWorldPtr oldGWorld )
  1616. {
  1617.     GWorldPtr            saveGWorld, newGWld;
  1618.     GDHandle            saveGDH;
  1619.     Rect                gwldRect;
  1620.     GWorldFlags            pixelState;
  1621.     ColorSearchUPP        whitenColSearchUPP;
  1622.     OSErr                err;
  1623.     PixMapHandle        newPix;
  1624.     PixMapHandle        oldPix;
  1625.         
  1626.     GetGWorld( &saveGWorld, &saveGDH );
  1627.     
  1628.     oldPix = GetGWorldPixMap(oldGWorld);
  1629.  
  1630.     GetGWorld( &saveGWorld, &saveGDH );
  1631.     
  1632.     gwldRect = oldGWorld->portRect;
  1633.     err = NewGWorld(&newGWld, (**oldPix).pixelSize, &gwldRect, nil, nil, 0 );
  1634.     
  1635.     if ( err == noErr )
  1636.     {
  1637.         newPix = GetGWorldPixMap(newGWld);
  1638.         pixelState = GetPixelsState( oldPix );
  1639.         (void)LockPixels( newPix );
  1640.         (void)LockPixels( GetGWorldPixMap(oldGWorld) );
  1641.         SetGWorld( oldGWorld, nil );
  1642.         ForeColor(blackColor);
  1643.         BackColor(whiteColor);
  1644.         SetGWorld( newGWld, nil );
  1645.         whitenColSearchUPP = NewColorSearchProc( whitenColorSearch );
  1646.         AddSearch( whitenColSearchUPP );
  1647.         ComputePixelValues( (**oldPix).pixelSize );
  1648.         CopyBits (
  1649.             (BitMap*) *oldPix,
  1650.             (BitMap*) *newPix,
  1651.             &gwldRect, 
  1652.             &gwldRect, 
  1653.             srcCopy, 
  1654.             nil);
  1655.         DelSearch( whitenColSearchUPP );
  1656.         DisposeRoutineDescriptor( whitenColSearchUPP );
  1657.         
  1658.         SetGWorld( oldGWorld, nil );
  1659.         CopyBits (
  1660.             (BitMap*) *newPix,
  1661.             (BitMap*) *oldPix,
  1662.             &gwldRect, 
  1663.             &gwldRect, 
  1664.             srcCopy, 
  1665.             nil);
  1666.         
  1667.         SetPixelsState( oldPix, pixelState );
  1668.         DisposeGWorld( newGWld );
  1669.     }
  1670.     
  1671.     SetGWorld( saveGWorld, saveGDH );
  1672.     
  1673.     SWSetStickyIfError( err );
  1674.     return err;
  1675. }
  1676.  
  1677.  
  1678. ///--------------------------------------------------------------------------------------
  1679. //    whitenColorSearch
  1680. ///--------------------------------------------------------------------------------------
  1681.  
  1682. pascal Boolean whitenColorSearch( RGBColor *RGB, long* position )
  1683. {
  1684.     #pragma unused(position)
  1685.     
  1686.         // Convert transparent pixels to 0, leaving others untouched
  1687.     if (    RGB->red == gSWTransparentColor.red        &&
  1688.             RGB->green == gSWTransparentColor.green    &&
  1689.             RGB->blue == gSWTransparentColor.blue    )
  1690.     {
  1691.         RGB->red = RGB->green = RGB->blue = SWTransparentRGBValue;        // set to zero
  1692.     }
  1693.  
  1694.     return false;
  1695. }
  1696.  
  1697.  
  1698. ///--------------------------------------------------------------------------------------
  1699. //    SWFastWhitenGWorld - same as SWWhitenGWorld, but faster, although this only works
  1700. //    in depths of 8 bits and above. Currently only called by SWUpdateSpriteFromPictResource.
  1701. ///--------------------------------------------------------------------------------------
  1702.  
  1703. SW_FUNC OSErr SWFastWhitenGWorld( GWorldPtr pictureGWorld )
  1704. {
  1705.     UInt32            transparent;
  1706.     GWorldPtr        saveGWorld;
  1707.     GDHandle        saveDevice;
  1708.     Ptr                baseAddr;
  1709.     long            rowBytes;
  1710.     long            width, height;
  1711.     long            depth, bytes;
  1712.     long            x, y;
  1713.     unsigned short    transparentValue;
  1714.     PixMapHandle    pictPix;
  1715.     GWorldFlags        pictPixelsState;
  1716.  
  1717.     pictPix = GetGWorldPixMap( pictureGWorld );
  1718.     
  1719.     width = pictureGWorld->portRect.right - pictureGWorld->portRect.left;
  1720.     height = pictureGWorld->portRect.bottom - pictureGWorld->portRect.top;
  1721.  
  1722.     depth = (**pictPix).pixelSize;
  1723.     ComputePixelValues(depth);
  1724.     transparentValue = SWTransparentRGBValue;
  1725.     
  1726.         // Exit if the depth is lower than 8 bits.
  1727.     if ( depth < 8 )
  1728.         return kWrongDepthErr;
  1729.     
  1730.     GetGWorld( &saveGWorld, &saveDevice);
  1731.     
  1732.     pictPixelsState = GetPixelsState( pictPix );
  1733.     LockPixels( pictPix );
  1734.  
  1735.     SetGWorld( pictureGWorld, (GDHandle) NULL);
  1736.     transparent = Color2Index( &gSWTransparentColor );
  1737.     
  1738.     START_32_BIT_MODE
  1739.  
  1740.     baseAddr = SWGetPixBaseAddr(pictPix);
  1741.     rowBytes = SWGetPixRowBytes(pictPix);
  1742.     
  1743.     bytes = (width * depth) >> 3;
  1744.     rowBytes -= bytes;
  1745.  
  1746.     switch ( depth )
  1747.     {
  1748.         case 8:
  1749.             {
  1750.                 UInt8    *dst = (UInt8 *) baseAddr;
  1751.                 
  1752.                 for ( y = 0; y < height; y++ )
  1753.                 {
  1754.                     for ( x = 0; x < width; x++ )
  1755.                     {
  1756.                         if ( *dst == transparent )
  1757.                             *dst++ = 0;
  1758.                         else
  1759.                             dst++;
  1760.                     }
  1761.                     dst = (UInt8 *) ( (char *) dst + rowBytes );
  1762.                 }
  1763.             }
  1764.             break;
  1765.         case 16:
  1766.             {
  1767.                 UInt16    *dst = (UInt16 *) baseAddr;
  1768.                 
  1769.                 transparent &= kAlphaMask16;
  1770.                 for ( y = 0; y < height; y++ )
  1771.                 {
  1772.                     for ( x = 0; x < width; x++ )
  1773.                     {
  1774.                         if ( (*dst & kAlphaMask16) == transparent )
  1775.                             *dst++ = 0;
  1776.                         else
  1777.                             dst++;
  1778.                     }
  1779.                     dst = (UInt16 *) ( (char *) dst + rowBytes );
  1780.                 }
  1781.             }
  1782.             break;
  1783.         case 32:
  1784.             {
  1785.                 UInt32    *dst = (UInt32 *) baseAddr;
  1786.                 
  1787.                 transparent &= kAlphaMask32;
  1788.                 for ( y = 0; y < height; y++ )
  1789.                 {
  1790.                     for ( x = 0; x < width; x++ )
  1791.                     {
  1792.                         if ( (*dst & kAlphaMask32) == transparent )
  1793.                             *dst++ = 0;
  1794.                         else
  1795.                             dst++;
  1796.                     }
  1797.                     dst = (UInt32 *) ( (char *) dst + rowBytes );
  1798.                 }
  1799.             }
  1800.             break;
  1801.         default:
  1802.             return paramErr;
  1803.     }
  1804.  
  1805.     END_32_BIT_MODE
  1806.     
  1807.     SetGWorld( saveGWorld, saveDevice);
  1808.  
  1809.     SetPixelsState( pictPix, pictPixelsState );
  1810.  
  1811.     return noErr;
  1812. }
  1813.  
  1814. #pragma mark -
  1815.  
  1816. ///--------------------------------------------------------------------------------------
  1817. //    SWClearStickyError
  1818. ///--------------------------------------------------------------------------------------
  1819.  
  1820. SW_FUNC void SWClearStickyError(void)
  1821. {
  1822.     gSWStickyError = noErr;
  1823. }
  1824.  
  1825. ///--------------------------------------------------------------------------------------
  1826. //    SWStickyError
  1827. ///--------------------------------------------------------------------------------------
  1828.  
  1829. SW_FUNC OSErr SWStickyError(void)
  1830. {
  1831.     return gSWStickyError;
  1832. }
  1833.  
  1834. ///--------------------------------------------------------------------------------------
  1835. //    SWSetStickyIfError
  1836. ///--------------------------------------------------------------------------------------
  1837.  
  1838. SW_FUNC void SWSetStickyIfError(OSErr errNum)
  1839. {
  1840.     if ( errNum != noErr )
  1841.         gSWStickyError = errNum;
  1842. }
  1843.  
  1844. #pragma mark -
  1845.  
  1846. ///--------------------------------------------------------------------------------------
  1847. // SWHasSystem7
  1848. ///--------------------------------------------------------------------------------------
  1849.  
  1850. SW_FUNC Boolean SWHasSystem7(void)
  1851. {
  1852.     long    versionNumber;
  1853.     OSErr    err;
  1854.     
  1855.     err = Gestalt( gestaltSystemVersion, &versionNumber );
  1856.  
  1857.     SWSetStickyIfError( err );
  1858.     return (err == noErr) && (versionNumber >= 0x0700);
  1859. }
  1860.  
  1861. #if (SW_ASSERT_ON == 1)
  1862. ///--------------------------------------------------------------------------------------
  1863. // SWAssertFail - called when the expression in SW_ASSERT() is false.
  1864. ///--------------------------------------------------------------------------------------
  1865.  
  1866. void SWAssertFail(char* filename, int lineNum)
  1867. {
  1868.     Str255            fileString = "\p";
  1869.     Str15            lineString;
  1870.     short            n, result;
  1871.     unsigned long    junkTime;
  1872.  
  1873.     NumToString((long)lineNum, lineString);
  1874.     
  1875.     for (n = 0; filename[n] != 0; n++)
  1876.     {
  1877.         fileString[n+1] = filename[n];
  1878.     }
  1879.     fileString[0] += n;
  1880.     
  1881.         // Call the CleanUpCallBack if there is one.
  1882.     if (gSWCleanUpCallBackP != NULL)
  1883.         (*gSWCleanUpCallBackP)();
  1884.     
  1885.     InitCursor();
  1886.     ParamText("\pAssertion failure! This program will now quit. The failure occurred here:", 
  1887.             fileString, lineString, "\pN/A");
  1888.     result = StopAlert(kAssertAlertID, NULL);
  1889.     
  1890.         // Make it beep if the dialog box couldn't be displayed for some reason.
  1891.     if (result < 0)
  1892.     {
  1893.         SysBeep(1);
  1894.         Delay(15, &junkTime); // Wait for beep to finish
  1895.     }
  1896.     
  1897.         // If a CleanUpSpriteWorld is installed, turn its VBL Syncing off.
  1898.     if (gSWCleanUpSpriteWorldP != NULL)
  1899.         SWSyncSpriteWorldToVBL(gSWCleanUpSpriteWorldP, false);
  1900.     
  1901.     ExitToShell();
  1902. }
  1903. #endif
  1904.  
  1905.